home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume21 / mailmerge / part01 next >
Encoding:
Text File  |  1991-07-26  |  9.3 KB  |  317 lines

  1. Newsgroups: comp.sources.misc
  2. From: Ajay Shah <ajayshah@alhena.usc.edu>
  3. Subject:  v21i043:  mailmerge - Mailmerge written in awk, Part01/01
  4. Message-ID: <1991Jul26.181156.26871@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 5dc6e660cb608e64b8eb18aead5d872e
  6. Date: Fri, 26 Jul 1991 18:11:56 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Ajay Shah <ajayshah@alhena.usc.edu>
  10. Posting-number: Volume 21, Issue 43
  11. Archive-name: mailmerge/part01
  12. Environment: AWK
  13.  
  14. This is a mailmerge program.  It is not aware of the typesetter
  15. being used; i.e., it can work with troff, TeX, or whatever.
  16. I searched on archie, and only turned up one such program, which
  17. seemed to be rather troff-oriented.
  18.  
  19. It takes two inputs:
  20.  
  21.     - a letter written using variables of the form NAME
  22.     - a database of people, which is just values for these variables.
  23.  
  24. Suppose the letter is in a file named "letter".  Suppose
  25. the database is in a file "list.of.people".  The command
  26.  
  27.     gawk -f mailmerge.awk -v L=letter list.of.people
  28.  
  29. will generate files mm_letter.1, mm_letter.2, etc in current
  30. directory.
  31.  
  32. The file demo.letter is a sample of a letter.  The use of mailmerge
  33. variables MUST be of the form FIELD, though uppercase is optional.
  34. As long as the fieldname you use agrees with the corresponding
  35. name in the datafile (including case) it will work out right.
  36.  
  37. If you're afraid about a field name clashing with something
  38. which should not be replaced, you could always use a fieldname
  39. of the form _NAME instead of NAME.  That should make clashes
  40. practically impossible.
  41.  
  42. The file demo.db is a sample database file. The first line 
  43. MUST define the layout of fields on the line.  The fields MUST 
  44. be pipe-delimited.  Extra blank lines anywhere are ok.
  45.  
  46. To test it on these demo files, doublecheck that the top of 
  47. the Makefile is ok, and say "make".
  48.  
  49. Ajay_Shah@rand.org
  50. Ajay Shah,
  51. The Rand Corporation,
  52. Thu Jul 25 21:46:02 PDT 1991
  53. #! /bin/sh
  54. # This is a shell archive.  Remove anything before this line, then unpack
  55. # it by saving it into a file and typing "sh file".  To overwrite existing
  56. # files, type "sh file -c".  You can also feed this as standard input via
  57. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  58. # will see the following message at the end:
  59. #        "End of shell archive."
  60. # Contents:  1.expected 2.expected Makefile README demo.db demo.letter
  61. #   mailmerge.awk
  62. # Wrapped by ajayshah@max on Thu Jul 25 21:47:43 1991
  63. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  64. if test -f '1.expected' -a "${1}" != "-c" ; then 
  65.   echo shar: Will not clobber existing file \"'1.expected'\"
  66. else
  67. echo shar: Extracting \"'1.expected'\" \(99 characters\)
  68. sed "s/^X//" >'1.expected' <<'END_OF_FILE'
  69. X
  70. XTo
  71. X    Sadhana Shah
  72. X    CMIE, Bombay
  73. X
  74. XDear Sad,
  75. X
  76. X    I almost forgot that July 8 was your birthday!
  77. X
  78. X    - me
  79. END_OF_FILE
  80. if test 99 -ne `wc -c <'1.expected'`; then
  81.     echo shar: \"'1.expected'\" unpacked with wrong size!
  82. fi
  83. # end of '1.expected'
  84. fi
  85. if test -f '2.expected' -a "${1}" != "-c" ; then 
  86.   echo shar: Will not clobber existing file \"'2.expected'\"
  87. else
  88. echo shar: Extracting \"'2.expected'\" \(106 characters\)
  89. sed "s/^X//" >'2.expected' <<'END_OF_FILE'
  90. X
  91. XTo
  92. X    Susan Thomas
  93. X    Rand Corporation
  94. X
  95. XDear Susan,
  96. X
  97. X    I almost forgot that July 30 was your birthday!
  98. X
  99. X    - me
  100. END_OF_FILE
  101. if test 106 -ne `wc -c <'2.expected'`; then
  102.     echo shar: \"'2.expected'\" unpacked with wrong size!
  103. fi
  104. # end of '2.expected'
  105. fi
  106. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  107.   echo shar: Will not clobber existing file \"'Makefile'\"
  108. else
  109. echo shar: Extracting \"'Makefile'\" \(469 characters\)
  110. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  111. X
  112. XNEWAWK=gawk
  113. X    # change that to be your copy of a new awk.
  114. X
  115. X#------------------------- Need not change anything below this line
  116. X
  117. Xtest :
  118. X    $(NEWAWK) -f mailmerge.awk -v L=demo.letter demo.db
  119. X    diff mm_demo.letter.1 1.expected
  120. X    diff mm_demo.letter.2 2.expected
  121. X    @echo If those two diffs went by fine, it works.
  122. X
  123. Xclean :
  124. X    rm -f mm_demo.letter.* readytopost
  125. X
  126. Xpost : clean
  127. X    shar * > /tmp/mailmerge.shar
  128. X    cat README /tmp/mailmerge.shar > readytopost
  129. X    rm -f /tmp/mailmerge.shar
  130. X
  131. END_OF_FILE
  132. if test 469 -ne `wc -c <'Makefile'`; then
  133.     echo shar: \"'Makefile'\" unpacked with wrong size!
  134. fi
  135. # end of 'Makefile'
  136. fi
  137. if test -f 'README' -a "${1}" != "-c" ; then 
  138.   echo shar: Will not clobber existing file \"'README'\"
  139. else
  140. echo shar: Extracting \"'README'\" \(1438 characters\)
  141. sed "s/^X//" >'README' <<'END_OF_FILE'
  142. X
  143. XThis is a mailmerge program.  It is not aware of the typesetter
  144. Xbeing used; i.e., it can work with troff, TeX, or whatever.
  145. XI searched on archie, and only turned up one such program, which
  146. Xseemed to be rather troff-oriented.
  147. X
  148. XIt takes two inputs:
  149. X
  150. X    - a letter written using variables of the form NAME
  151. X    - a database of people, which is just values for these variables.
  152. X
  153. XSuppose the letter is in a file named "letter".  Suppose
  154. Xthe database is in a file "list.of.people".  The command
  155. X
  156. X    gawk -f mailmerge.awk -v L=letter list.of.people
  157. X
  158. Xwill generate files mm_letter.1, mm_letter.2, etc in current
  159. Xdirectory.
  160. X
  161. XThe file demo.letter is a sample of a letter.  The use of mailmerge
  162. Xvariables MUST be of the form FIELD, though uppercase is optional.
  163. XAs long as the fieldname you use agrees with the corresponding
  164. Xname in the datafile (including case) it will work out right.
  165. X
  166. XIf you're afraid about a field name clashing with something
  167. Xwhich should not be replaced, you could always use a fieldname
  168. Xof the form _NAME instead of NAME.  That should make clashes
  169. Xpractically impossible.
  170. X
  171. XThe file demo.db is a sample database file. The first line 
  172. XMUST define the layout of fields on the line.  The fields MUST 
  173. Xbe pipe-delimited.  Extra blank lines anywhere are ok.
  174. X
  175. XTo test it on these demo files, doublecheck that the top of 
  176. Xthe Makefile is ok, and say "make".
  177. X
  178. XAjay_Shah@rand.org
  179. XAjay Shah,
  180. XThe Rand Corporation,
  181. XThu Jul 25 21:46:02 PDT 1991
  182. END_OF_FILE
  183. if test 1438 -ne `wc -c <'README'`; then
  184.     echo shar: \"'README'\" unpacked with wrong size!
  185. fi
  186. # end of 'README'
  187. fi
  188. if test -f 'demo.db' -a "${1}" != "-c" ; then 
  189.   echo shar: Will not clobber existing file \"'demo.db'\"
  190. else
  191. echo shar: Extracting \"'demo.db'\" \(121 characters\)
  192. sed "s/^X//" >'demo.db' <<'END_OF_FILE'
  193. X#LAYOUT FIRSTNAME NAME BIRTHDAY ADDRESS
  194. XSad|Sadhana Shah|July 8|CMIE, Bombay
  195. XSusan|Susan Thomas|July 30|Rand Corporation
  196. END_OF_FILE
  197. if test 121 -ne `wc -c <'demo.db'`; then
  198.     echo shar: \"'demo.db'\" unpacked with wrong size!
  199. fi
  200. # end of 'demo.db'
  201. fi
  202. if test -f 'demo.letter' -a "${1}" != "-c" ; then 
  203.   echo shar: Will not clobber existing file \"'demo.letter'\"
  204. else
  205. echo shar: Extracting \"'demo.letter'\" \(94 characters\)
  206. sed "s/^X//" >'demo.letter' <<'END_OF_FILE'
  207. X
  208. XTo
  209. X    NAME
  210. X    ADDRESS
  211. X
  212. XDear FIRSTNAME,
  213. X
  214. X    I almost forgot that BIRTHDAY was your birthday!
  215. X
  216. X    - me
  217. END_OF_FILE
  218. if test 94 -ne `wc -c <'demo.letter'`; then
  219.     echo shar: \"'demo.letter'\" unpacked with wrong size!
  220. fi
  221. # end of 'demo.letter'
  222. fi
  223. if test -f 'mailmerge.awk' -a "${1}" != "-c" ; then 
  224.   echo shar: Will not clobber existing file \"'mailmerge.awk'\"
  225. else
  226. echo shar: Extracting \"'mailmerge.awk'\" \(1743 characters\)
  227. sed "s/^X//" >'mailmerge.awk' <<'END_OF_FILE'
  228. X
  229. XBEGIN {
  230. X    # recall variable L has been setup.
  231. X    # first, we swallow the file L into the (integer indexed) array
  232. X    # "let_lines".  The variable "line" contains the number of
  233. X    # lines in this file, at the end.
  234. X    line = 0;
  235. X    do {
  236. X        eof = getline s < L;
  237. X        if (eof > 0) {
  238. X                line++; 
  239. X                let_lines[line] = s;
  240. X            }
  241. X    } while (eof > 0);
  242. X    if (line == 0) {
  243. X        print "mailmerge.awk: File " L " does not exist." > "/dev/tty";
  244. X        goch = 1; exit 1;
  245. X    }
  246. X}
  247. X
  248. X{taken = 0}
  249. X    # "This line has not yet been dealt with.
  250. X
  251. X(NF == 0) {taken = 1}
  252. X    # Ignore blank lines (i.e., those with no fields).
  253. X
  254. X# Now catch the LAYOUT line:
  255. X/^#LAYOUT/ {
  256. X    taken = 1;
  257. X    if (NF == 1) {
  258. X        print "mailmerge.awk: LAYOUT must contain some fields!" > "/dev/tty";
  259. X        goch = 1; exit 1;
  260. X    }
  261. X    for (i=2; i<=NF; i++) position[$i] = i-1;
  262. X    fnum = NF-1;
  263. X        # just gobble layout into "position" associative array.
  264. X    gotlayout = 1;
  265. X}
  266. X
  267. X# Finally, if you have a line with taken == 0, it's a normal DB line.
  268. X(taken == 0) {
  269. X    if (gotlayout == 0) {
  270. X        print "mailmerge.awk: Database file must contain a LAYOUT line before any real data." > "/dev/tty";
  271. X        goch = 1; exit 1;
  272. X    }
  273. X
  274. X    print "";
  275. X    print "Input line = " substr($0, 1, 50) " ...";
  276. X
  277. X    n = split($0, words, "|");
  278. X    if (n != fnum) {
  279. X        print "mailmerge.awk: Error on Line " NR " of database" > "/dev/tty";
  280. X        print "    (Expect " fnum " fields, got " n ")" > "/dev/tty";
  281. X    }
  282. X
  283. X    # Now we're all set to generate code.
  284. X    # First generate filename.
  285. X    ofn = "mm_" L "." (NR-1);
  286. X    print "Generating file named " ofn;
  287. X
  288. X    # run over lines of letter, doing find-replace.
  289. X    for (i=1; i<=line; i++) {
  290. X        s = let_lines[i];
  291. X        for (v in position)
  292. X            if (0 != index(s, v))    # only try replace if it matches
  293. X                gsub(v, words[position[v]], s);
  294. X        print s > ofn;
  295. X    }
  296. X}
  297. X
  298. XEND {
  299. X    if (goch == 1) exit 1;
  300. X}
  301. END_OF_FILE
  302. if test 1743 -ne `wc -c <'mailmerge.awk'`; then
  303.     echo shar: \"'mailmerge.awk'\" unpacked with wrong size!
  304. fi
  305. # end of 'mailmerge.awk'
  306. fi
  307. echo shar: End of shell archive.
  308. exit 0
  309.  
  310. -- 
  311. _______________________________________________________________________________
  312. Ajay Shah, (213)734-3930, ajayshah@usc.edu
  313.                              The more things change, the more they stay insane.
  314. _______________________________________________________________________________
  315.  
  316. exit 0 # Just in case...
  317.